﻿#include "readsession.h"
#include "utils.h"

//#include <netinet/in.h>
#include <winsock.h>
#include <QFile>

namespace TFTP {

ReadSession::~ReadSession()
{
    delete buffer;
}


void ReadSession::loadFile()
{
    int len = m_currentFile->size();
    buffer = new QByteArray();
    buffer->resize(len);

	switch(currentMode)
	{
		case NetAscii:
			qWarning("NetAscii transfers not supported");
			break;
		case Octet:
            uint32_t actual = m_currentFile->read(buffer->data(), buffer->size());
            if ( actual != buffer->size() ) // Shouldn't be used
                buffer->resize(actual);
			break;
	}
}


bool ReadSession::sendData()
{
    quint32  offset = currentBlock * 512;
    qint32  length = buffer->size() - offset;
    if ( length < 0 ){
		return true;
    }

    length = length > 512 ? 512 : length;

    QByteArray dgram;
    dgram.resize(length + 4);

	wordOfArray(dgram)[0] = htons( (quint16 )DATA );
	wordOfArray(dgram)[1] = htons( currentBlock+1 );
	
    memcpy(dgram.data() + 4, buffer->data() + offset, length);
	
    if( ti.sd->writeDatagram(dgram.data(), dgram.size(), ti.dAddr, ti.dPort) == -1 )
    {
        qWarning("发送数据包时出错 [%d]", ti.sd->error() );
    }

	return false;
}


bool ReadSession::parseAck(const QByteArray &dgram)
{
	if ( ntohs(wordOfArray(dgram)[0]) != ACK )
	{
        qWarning("不是ACK");
		return true;
	}
	
	if ( currentBlock != ntohs(wordOfArray(dgram)[1]) -1 )
	{
		qWarning("Expected %d, got %d", currentBlock+1, ntohs(wordOfArray(dgram)[1]));
        ti.sendError(IllegalOp, "块序列错误");
		return true;
	}
	
	currentBlock = ntohs(wordOfArray(dgram)[1]);
	
	return sendData();
}

};
